//
//  NetWorkTools.swift
//  Tanenbaum_blog
//
//  Created by Tanenbaum on 15/7/30.
//  Copyright © 2015年 GZJ. All rights reserved.
//

import UIKit
import AFNetworking


private let ZuoJErrorDomainName = "com.gaizuoia.error.network"

//枚举封装错误信息
private enum ZuoJError:Int {
    
    case emptyDataError = -1
    case emptyTokenError = -2
    
    private var errorDescription: String {
        switch self {
            
        case .emptyDataError : return"空数据"
        case .emptyTokenError : return"Token为空"
            
        }
    }
    
    private func error() ->NSError {
        
        return NSError (domain: ZuoJErrorDomainName, code: rawValue, userInfo: [ZuoJErrorDomainName:errorDescription])
    }
}
private enum ZuoJNetMethod: String {
    
    case GET = "GET"
    
    case POST = "POST"
}
class NetWorkTools: AFHTTPSessionManager {
    
    
    //设置单例
    static let sharedTools: NetWorkTools = {
        
        let tools = NetWorkTools(baseURL: NSURL(string: "https://api.weibo.com/"))
        
        
        //设置数据解析数据类型
        
        tools.responseSerializer.acceptableContentTypes = NSSet(objects: "application/xml", "text/xml", "text/plain","application/json") as Set<NSObject>
        return tools
        }()
    
    private let clientid = "2840023602"
    private let appsecret = "1eefbadf5df9eaaebf7fe73b309af854"
    let redirecturi = "http://www.baidu.com"
    
    // 给网络回调设置新的别名
    typealias ZuoJFinishedCallBack = (result:[String:AnyObject]?,error:NSError?) -> ()
    
    private func tokenDict(finished:ZuoJFinishedCallBack) ->[String: AnyObject]? {
        
        // 判断 token 是否存在
        if UserAccount.shareAccount?.access_token == nil {
            
            let error = ZuoJError.emptyTokenError.error()
            
            finished(result: nil, error: error)
             return nil
        }
        
        return ["access_token": UserAccount.shareAccount!.access_token!]
        
    }
    
    func loadStatus(since_id: Int, max_id: Int, finished:ZuoJFinishedCallBack){
        
        guard var params = tokenDict(finished)else {
            return
        }
        
        if since_id > 0 {
            params["since_id"] = since_id
        }
        if max_id > 0 {
            params["max_id"] = max_id - 1
        }
        
        let urlString = "2/statuses/home_timeline.json"
        
        request(ZuoJNetMethod.GET, urlString: urlString, parameters: params, finished: finished)
    }
    
    func postStatus(status:String ,image:UIImage?, finished:ZuoJFinishedCallBack) {
        
        guard var params = tokenDict(finished)else {
            return
        }
        params["status"] = status
        
        if image == nil {
            
            request(ZuoJNetMethod.POST, urlString: "2/statuses/update.json", parameters: params, finished: finished)
        } else {
            upload("https://upload.api.weibo.com/2/statuses/upload.json", image: image!, params: params, finished: finished)
        }
    }
    // MARK: --加载用户数据
    /// 加载用户信息
    func loadUserInfo(uid: String, finished: ZuoJFinishedCallBack) {
        
      
        guard var params = tokenDict(finished) else {
            
            return
        }
        
        let urlString = "2/users/show.json"
        params["uid"] = uid
        
        request(ZuoJNetMethod.GET, urlString: urlString, parameters: params, finished: finished)
    }
    
    //MARK:--授权 oauth认证
    func oauth() ->NSURL {
        
        let urlString = "https://api.weibo.com/oauth2/authorize?client_id=\(clientid)&redirect_uri=\(redirecturi)"
        
        return NSURL(string: urlString)!
    }
    
    //获取token
    func loadAccessToken(code:String,finished:ZuoJFinishedCallBack) {
        
        let urlString = "https://api.weibo.com/oauth2/access_token"
        let params = ["client_id":clientid,
            "client_secret":appsecret,
            "grant_type":"authorization_code",
            "code":code,
            "redirect_uri":redirecturi]
        
        request(ZuoJNetMethod.POST, urlString: urlString, parameters: params, finished: finished)
    }
    
    private func upload(urlString:String,image:UIImage,params:[String:AnyObject],finished:ZuoJFinishedCallBack) {
        
        let successCallBack: (NSURLSessionDataTask!,AnyObject!) -> Void = { (_, JSON) -> Void in
            
            if let result = JSON as? [String: AnyObject] {
                
                finished(result: result, error: nil)
            }else {
                
                finished(result: nil, error: ZuoJError.emptyDataError.error())
            }
        }
        
        let failedCallBack: (NSURLSessionDataTask!,NSError!) ->Void = { (_, error) -> Void in
            
            print("GET回调错误")
            print(error)
            finished(result: nil, error: error)
        }
        
        
        POST(urlString, parameters: params, constructingBodyWithBlock: { (formData) -> Void in
            
            let data = UIImagePNGRepresentation(image)
            formData.appendPartWithFileData(data, name: "pic", fileName: "xxx", mimeType: "image/png")
            }, success: successCallBack, failure: failedCallBack)
    }
    //MARK： 封装AFN的网络框架，接触网络的代码都集中起来，便于管理和更改
    //网络方法的抽取
    private func request(method:ZuoJNetMethod, urlString:String, parameters:[String: AnyObject],finished:ZuoJFinishedCallBack) {
        
        
        let successCallBack: (NSURLSessionDataTask!,AnyObject!) -> Void = { (_, JSON) -> Void in
            
            if let result = JSON as? [String: AnyObject] {
                
                finished(result: result, error: nil)
            }else {
              
                finished(result: nil, error: ZuoJError.emptyDataError.error())
            }
         }
            
        let failedCallBack: (NSURLSessionDataTask!,NSError!) ->Void = { (_, error) -> Void in
                
                print("GET回调错误")
                print(error)
                finished(result: nil, error: error)
        }
      
        switch method {
            
        case .GET:
            GET(urlString, parameters: parameters, success: successCallBack, failure: failedCallBack)
        case .POST:
            POST(urlString, parameters: parameters, success: successCallBack, failure: failedCallBack)
        }
    }
    
}


